
using Sustainalytics.CRT.Synchronization.Entities;
using Sustainalytics.ESG.Entities;
using System;
using System.Collections.Generic;
using System.Linq;

using Xunit;

namespace Sustainalytics.CRT.Synchronization.Tests
{


    [Trait("Category", "Unit")]
    public class FocusedRatingsMarketCapitalizationTest
    {
        private static readonly Guid CompanyId = Guid.NewGuid();

        private readonly ESG.Entities.RPCompanyESGComputationResult _fake = new ESG.Entities.RPCompanyESGComputationResult() { Id = CompanyId, OverallPerformance = new RPPerformance { Score = 50 } };
        private MarketCapitalizationManager _sut;

        [Fact]
        public void Given_a_list_of__interleaved_research_type_FinancialData_Should_return_at_most_5_elements_only_fullEgs_companies()
        {
            var marketCapInformation = new List<MarketCapInfo>
                                           {
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test2", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test3", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test4", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = CompanyId,MarketCap = 77        ,PeerGroup="peer",Score=0},
                                               new MarketCapInfo{CompanyName = "test5", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = Guid.NewGuid(),MarketCap = 76.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test6", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 74.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test7", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 73.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test8", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 73.5,PeerGroup="peer",Score=10}
                                           };
            this._sut = new MarketCapitalizationManager(marketCapInformation, 3);
            var result = this._sut.GetCompanyPeersInformation(this._fake);
            var expected = marketCapInformation.Where(x => x.HasEsgResearch || x.Id == CompanyId).Select(x => x.Id).OrderByDescending(x => x).ToArray();
            Assert.Equal(expected, result.Peers.Select(x => x.CompanyId).OrderByDescending(x => x).ToArray());
        }

        [Fact]
        public void Given_a_list_of__interleaved_research_type_FinancialData_Should_return_at_most_5_elements_only_fullEgs_companies_2()
        {
            var marketCapInformation = new List<MarketCapInfo>
                                           {
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("A6EB1430-B1B4-48BF-B194-79D6E32C824F"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("C7693952-AA75-479C-9204-17B55A8E841D"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("6DC2E910-586B-49BB-A6EC-0EE3F270AFAD"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test2", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("87D8B257-DE17-403F-8F7F-2C3101286FC2"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test3", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("67A10871-46F9-41C0-B47A-227722C67B46"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test4", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = CompanyId,MarketCap = 77        ,PeerGroup="peer",Score=0},
                                               new MarketCapInfo{CompanyName = "test5", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("6EA7EF16-FE5F-4F04-8931-A733733AD772"),MarketCap = 76.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test6", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("E11CB8AC-B927-4D07-B713-7821AE795304"),MarketCap = 74.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test7", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("1AB46526-D149-4663-9079-16387251690C"),MarketCap = 73.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test8", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("42C1A1E0-2633-4260-BC76-A3CB279A69C1"),MarketCap = 73.5,PeerGroup="peer",Score=10}
                                           };
            this._sut = new MarketCapitalizationManager(marketCapInformation, 5);
            var result = this._sut.GetCompanyPeersInformation(this._fake);
            var expected = new[] { 5, 4, 2, 8, 9 }.Select(x => marketCapInformation[x].Id).OrderByDescending(x => x).ToArray();
            Assert.Equal(expected, result.Peers.Select(x => x.CompanyId).OrderByDescending(x => x).ToArray());
        }

        [Fact]
        public void Given_a_list_of__interleaved_research_type_FinancialData_Should_return_at_most_5_elements_only_fullEgs_companies_3()
        {
            var marketCapInformation = new List<MarketCapInfo>
                                           {
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("A6EB1430-B1B4-48BF-B194-79D6E32C824F"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("C7693952-AA75-479C-9204-17B55A8E841D"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("6DC2E910-586B-49BB-A6EC-0EE3F270AFAD"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test2", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("87D8B257-DE17-403F-8F7F-2C3101286FC2"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test3", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("67A10871-46F9-41C0-B47A-227722C67B46"),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test4", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = CompanyId,MarketCap = 77        ,PeerGroup="peer",Score=0},
                                               new MarketCapInfo{CompanyName = "test5", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("6EA7EF16-FE5F-4F04-8931-A733733AD772"),MarketCap = 76.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test6", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = new Guid("E11CB8AC-B927-4D07-B713-7821AE795304"),MarketCap = 74.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test7", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("1AB46526-D149-4663-9079-16387251690C"),MarketCap = 73.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test8", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = new Guid("42C1A1E0-2633-4260-BC76-A3CB279A69C1"),MarketCap = 73.5,PeerGroup="peer",Score=10}
                                           };
            _sut = new MarketCapitalizationManager(marketCapInformation, 5);
            var result = _sut.GetCompanyPeersInformation(this._fake);
            var expected = new[] { 5, 2, 0, 8, 9 }.Select(x => marketCapInformation[x].Id).OrderByDescending(x => x).ToArray();
            Assert.Equal(expected, result.Peers.Select(x => x.CompanyId).OrderByDescending(x => x).ToArray());
        }

        [Fact]
        public void Given_a_list_of_FinancialData_return_at_most_5_elements()
        {
            var marketCapInformation = new List<MarketCapInfo>
                                           {
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test2", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test3", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test4", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = CompanyId,MarketCap = 77        ,PeerGroup="peer",Score=0},
                                               new MarketCapInfo{CompanyName = "test5", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 76.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test6", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 74.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test7", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 73.5,PeerGroup="peer",Score=10}
                                           };
            this._sut = new MarketCapitalizationManager(marketCapInformation, 3);
            var result = this._sut.GetCompanyPeersInformation(this._fake);
            Assert.Equal(result.Peers.Length, 5);
        }

        [Fact]
        public void Given_a_list_of_FinancialData_Should_return_at_most_5_elements_only_fullEgs_companies()
        {
            var marketCapInformation = new List<MarketCapInfo>
                                           {
                                               new MarketCapInfo{CompanyName = "test1", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test2", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test3", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = Guid.NewGuid(),MarketCap = 78.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test4", HasEsgResearch = false, HasFocusedRatingsReasearch = true,Id = CompanyId,MarketCap = 77        ,PeerGroup="peer",Score=0},
                                               new MarketCapInfo{CompanyName = "test5", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 76.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test6", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 74.5,PeerGroup="peer",Score=10},
                                               new MarketCapInfo{CompanyName = "test7", HasEsgResearch = true, HasFocusedRatingsReasearch = false,Id = Guid.NewGuid(),MarketCap = 73.5,PeerGroup="peer",Score=10}
                                           };
            this._sut = new MarketCapitalizationManager(marketCapInformation, 3);
            var result = this._sut.GetCompanyPeersInformation(this._fake);
            Assert.Equal(result.Peers.Length, 4);
        }
    }
}